/**
 * 判断是否是基本数据类型
 * @param {*} value
 * @returns
 */
function isPrimitive(value) {
  return (
    typeof value === "string" ||
    typeof value === "number" ||
    typeof value === "symbol" ||
    typeof value === "boolean"
  );
}

/**
 * 判断是否是一个js对象
 * @param {*} value
 * @returns
 */
function isObject(value) {
  return Object.prototype.toString.call(value) === "[object Object]";
}

/**
 * 浅拷贝
 * @param {*} value
 * @returns
 */
shallowClone = function (value) {
  let result;

  if (isPrimitive(value)) {
    // 如果是基本数据类型，则直接返回
    return value;
  } else if (Array.isArray(value)) {
    // 处理数组
    result = [...value];
  } else if (isObject(value)) {
    // 处理对象
    result = { ...value };
  }

  return result;
};

/**
 * 深拷贝
 * @param {*} value
 * @returns
 */
deepClone = function (value, deep = Infinity, objectStack = []) {
  if (deep <= 0 || objectStack.includes[value]) {
    // 深度超过限制 或 子对象内部引用了父级对象
    return null; // 停止克隆
  }

  if (value instanceof Date) {
    return new Date(value);
  }

  if (Array.isArray(value)) {
    return value.map((item) =>
      typeof item === "object"
        ? deepClone(item, deep - 1, objectStack.concat([value]))
        : item
    );
  }

  const result = shallowClone(value);

  Object.entries(result).forEach(([k, v]) => {
    if (typeof v === "object") {
      result[k] = deepClone(v, deep - 1, objectStack.concat([value]));
    }
  });
  return result;
};

/**
 * 拷贝一个值
 * @param {*} value
 * @param {*} deep 是否深拷贝
 */
exports.clone = function (value, deep = false) {
  if (deep) {
    return deepClone(value);
  }
  return shallowClone(value);
};
